﻿#include "widget.h"

#include <QApplication>
#include <DbgHelp.h>

LONG crashHandler(EXCEPTION_POINTERS *pException)
{
    QString curDataTime = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
    QString dumpName = curDataTime + ".dmp";

    HANDLE dumpFile = CreateFile((LPCWSTR)QString("./" + dumpName).utf16(),GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if(dumpFile != INVALID_HANDLE_VALUE)
    {
        MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
        dumpInfo.ExceptionPointers = pException;
        dumpInfo.ThreadId = GetCurrentThreadId();
        dumpInfo.ClientPointers = TRUE;

        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),dumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
        CloseHandle(dumpFile);
    }
    else
    {
        qDebug() << "dumpFile not vaild";
    }

    return EXCEPTION_EXECUTE_HANDLER;
}

//防止CRT（C runtime）函数报错可能捕捉不到
void DisableSetUnhandledExceptionFilter()
{
    void* addr = (void*)GetProcAddress(LoadLibrary(L"kernel32.dll"), "SetUnhandledExceptionFilter");
    if(addr)
    {
        unsigned char code[16];
        int size = 0;

        code[size++] = 0x33;
        code[size++] = 0xC0;
        code[size++] = 0xC2;
        code[size++] = 0x04;
        code[size++] = 0x00;

        DWORD dwOldFlag, dwTempFlag;
        VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);
        WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);
        VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);
    }
}

int main(int argc, char *argv[])
{
    //注冊异常捕获函数
//    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)crashHandler);
//    DisableSetUnhandledExceptionFilter();

    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
